/*
 * @Author: wuqingchun
 * @Date: 2024-04-01 13:28:43
 * @Description: 定时器实现
 * @LastEditors: wuqingchun
 * @LastEditTime: 2024-04-01 19:38:16
 */
#include "utcp_timer.h"

UTCPTimer::UTCPTimer(/* args */)
{
}

UTCPTimer::~UTCPTimer()
{
}

int32_t UTCPTimer::Start()
{
    m_bRunning = true;
    m_objThread = std::thread([this](){
        while (m_bRunning) 
        {
            Run();
        }
    });

    return 0;
}

void UTCPTimer::Run()
{
    // 获取最小的超时时间

    bool bEmpty = false;

    {
        std::unique_lock<std::mutex> objULock(m_objMutex);
        bEmpty = m_mapTasks.empty();
    }
    
    if (bEmpty)
    {
        std::unique_lock<std::mutex> objULock(m_objMutex);
        m_objCondVar.wait(objULock);

        return;
    }

    TimerTask stTask;
    {
        std::unique_lock<std::mutex> objULock(m_objMutex);
        auto it = m_mapTasks.begin();
        stTask = it->second;
        m_mapTasks.erase(it);
    }

    TIMER_TIMER_POINT tpNow = std::chrono::steady_clock::now();
    if (tpNow < stTask.tpTimeout)
    {
        std::unique_lock<std::mutex> objULock(m_objMutex);
        m_objCondVar.wait_until(objULock, stTask.tpTimeout);
    }

    // 执行回调函数
    stTask.CallBack(stTask.Arg);

    if (stTask.Interval > 0)
    {
        // 周期性定时任务
        stTask.tpTimeout = std::chrono::steady_clock::now() + std::chrono::nanoseconds(stTask.Interval);
        std::lock_guard<std::mutex> objLG(m_objMutex);
        m_mapTasks.emplace(stTask.tpTimeout, stTask);
    }
}

void UTCPTimer::AddTask(uint32_t uiTimeout, uint32_t uiInterval, std::function<void (void*)> pfCallback)
{
    std::lock_guard<std::mutex> objLG(m_objMutex);    
    TimerTask stTask = {std::chrono::steady_clock::now() + std::chrono::nanoseconds(uiTimeout), 
                        uiInterval, pfCallback, nullptr};
    m_mapTasks.emplace(stTask.tpTimeout, stTask);
    m_objCondVar.notify_all();
}